<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Form 表单2</title>
	<link rel="stylesheet" href="../static/css/reset.css">
	<script src="../static/js/vue.global.prod.js"></script>
	<script src="../static/js/antd.min.js"></script>
	<script src="../static/js/icons_antd.js"></script>
</head>
<style>
.search-result-list {
	margin-top: 16px;
	border: 1px dashed #e9e9e9;
	border-radius: 2px;
	background-color: #fafafa;
	min-height: 200px;
	text-align: center;
	padding-top: 80px;
}
</style>
<body>

<div id="app">
	<a-affix :offset-top="10"><div id="form_links"></div></a-affix><script src="links.js"></script><script>form_link();</script>
	
	<a-divider class="a-divi" orientation="left">嵌套结构与校验信息</a-divider><!-- =============================================================== -->
	<p class="desc">name 属性支持嵌套数据结构。通过 validateMessages 或 message 自定义校验信息模板，模板内容可参考此处。</p>
	<a-form :model="formState11" v-bind="layout11" name="nest-messages" :validate-messages="validateMessages11"
		@finish="onFinish11" @finish-Failed="onFinishFailed11" style="width: 800px;">
		<a-form-item :name="['user', 'name']" label="Name" :rules="[{ required: true }]">
			<a-input v-model:value="formState11.user.name"></a-input>
		</a-form-item>
		<a-form-item :name="['user', 'email']" label="Email" :rules="[{ type: 'email' }]">
			<a-input v-model:value="formState11.user.email"></a-input>
		</a-form-item>
		<a-form-item :name="['user', 'age']" label="Age" :rules="[{ type: 'number', min: 0, max: 99 }]">
			<a-input-number v-model:value="formState11.user.age"></a-input-number>
		</a-form-item>
		<a-form-item :name="['user', 'website']" label="Website">
			<a-input v-model:value="formState11.user.website"></a-input>
		</a-form-item>
		<a-form-item :name="['user', 'introduction']" label="Introduction">
			<a-textarea v-model:value="formState11.user.introduction"></a-textarea>
		</a-form-item>
		<a-form-item :wrapper-col="{ ...layout11.wrapperCol, offset: 8 }">
			<a-button type="primary" html-type="submit">Submit</a-button>
		</a-form-item>
	</a-form>
	
	<a-divider class="a-divi" orientation="left">自定义表单控件</a-divider><!-- =============================================================== -->
	<p class="desc">自定义或第三方的表单控件，也可以与 Form 组件一起使用。只要该组件注入 useInjectFormItemContext 并调用相应方法。</p>
	<p class="desc">【活生生又做回Antd框架了】</p>
	<a-form :model="formState12" name="customized_form_controls" layout="inline" style="width: 800px;margin-left: 20px;"
		@finish="onFinish11" @finish-Failed="onFinishFailed11">
		<a-form-item :name="['price', 'number']" label="Price" :rules="[{ validator: checkPrice12 }]">
			<a-input-number v-model:value="formState12.price.number"></a-input-number>
		</a-form-item>
		<a-form-item>
			<a-button type="primary" html-type="submit">Submit</a-button>
		</a-form-item>
	</a-form>
	
	<a-divider class="a-divi" orientation="left">高级搜索</a-divider><!-- =============================================================== -->
	<p class="desc">三列栅格式的表单排列方式，常用于数据表格的高级搜索。有部分定制的样式代码，由于输入标签长度不确定，需要根据具体情况自行调整。</p>
	<a-space direction="vertical" style="width: 90%;margin-left: 20px">
		<a-form ref="formRef13" :model="formState13" name="advanced_search" class="ant-advanced-search-form"
			@finish="onFinish11" @finish-Failed="onFinishFailed11">
			<a-row :gutter="24">
				<template v-for="i in 10" :key="i">
					<a-col v-show="expand13 || i <= 6" :span="8">
						<a-form-item :name="`field-${i}`" :label="`field-${i}`"
							:rules="[{ required: true, message: 'input something' }]">
							<a-input v-model:value="formState13[`field-${i}`]" placeholder="placeholder"></a-input>
						</a-form-item>
					</a-col>
				</template>
			</a-row>
			<a-row>
				<a-col :span="24" style="text-align: right">
					<a-button type="primary" html-type="submit">Search</a-button>
					<a-button style="margin: 0 8px" @click="resetForm13">Clear</a-button>
					<a style="font-size: 12px" @click="expand13 = !expand13">
						<template v-if="expand13">
							<Up-Outlined class="ant-icon"></Up-Outlined>
						</template>
						<template v-else>
							<Down-Outlined  class="ant-icon"></Down-Outlined>
						</template>
						Collapse
					</a>
				</a-col>
			</a-row>
		</a-form>
		<div class="search-result-list">Search Result List</div>
	</a-space>
	
	<a-divider class="a-divi" orientation="left">复杂的动态增减表单项</a-divider><!-- =============================================================== -->
	<p class="desc">这个例子演示了一个表单中包含多个表单控件的情况。</p>
	<a-form ref="formRef14" :model="formState14" name="dynamic_form_nest_item" style="width: 90%;margin-left: 20px"
		@finish="onFinish11" @finish-Failed="onFinishFailed11">
		<a-form-item name="area" label="Area" :rules="[{ required: true, message: 'Missing area' }]">
			<a-select v-model:value="formState14.area" :options="areas14"></a-select>
		</a-form-item>
		<a-space v-for="(sight, index) in formState14.sights" :key="sight.id" style="display: flex; margin-bottom: 8px" align="baseline">
			<a-form-item label="Sight" :name="['sights', index, 'value']" :rules="{required: true, message: 'Missing sight',}">
				<a-select v-model:value="sight.value" :disabled="!formState14.area"
					:options="(sights14[formState14.area] || []).map(a => ({ value: a }))" style="width: 130px">
				</a-select>
			</a-form-item>
			<a-form-item label="Price" :name="['sights', index, 'price']" :rules="{required: true, message: 'Missing price',}">
				<a-input v-model:value="sight.price"></a-input>
			</a-form-item>
			<Minus-Circle-Outlined @click="removeSight14(sight)" class="ant-icon"></Minus-Circle-Outlined>
		</a-space>
		<a-form-item>
			<a-button type="dashed" block @click="addSight14">
				<Plus-Outlined class="ant-icon"></Plus-Outlined>
				Add sights
			</a-button>
		</a-form-item>
		<a-form-item>
			<a-button type="primary" html-type="submit">Submit</a-button>
		</a-form-item>
	</a-form>
	
	<a-divider class="a-divi" orientation="left">动态增减嵌套字段</a-divider><!-- =============================================================== -->
	<p class="desc">通过数组 name 绑定嵌套字段</p>
	<a-form ref="formRef15" :model="formState15" name="dynamic_form_nest_item" style="width: 500px;margin-left: 20px"
		@finish="onFinish11" @finish-Failed="onFinishFailed11">
		<a-space v-for="(user, index) in formState15.users" :key="user.id" style="display: flex; margin-bottom: 8px" align="baseline">
			<a-form-item :name="['users', index, 'first']" :rules="{required: true, message: 'Missing first name',}">
				<a-input v-model:value="user.first" placeholder="First Name"></a-input>
			</a-form-item>
			<a-form-item :name="['users', index, 'last']" :rules="{required: true, message: 'Missing last name',}">
				<a-input v-model:value="user.last" placeholder="Last Name"></a-input>
			</a-form-item>
			<Minus-Circle-Outlined @click="removeUser15(user)" class="ant-icon"></Minus-Circle-Outlined>
		</a-space>
		<a-form-item>
			<a-button type="dashed" block @click="addUser15">
				<Plus-Outlined class="ant-icon"></Plus-Outlined> Add user
			</a-button>
		</a-form-item>
		<a-form-item>
			<a-button type="primary" html-type="submit">Submit</a-button>
		</a-form-item>
	</a-form>
	
	<a-divider class="a-divi" orientation="left">动态校验规则</a-divider><!-- =============================================================== -->
	<p class="desc">根据不同情况执行不同的校验规则。</p>
	<a-form ref="formRef16" :model="formState16" name="dynamic_rule" v-bind="formItemLayout16">
		<a-form-item label="Username" name="username" :rules="[{ required: true, message: 'Please input your username!' }]">
			<a-input v-model:value="formState16.username"></a-input>
		</a-form-item>
	
		<a-form-item label="Nickname" name="nickname" :rules="[{ required: formState16.checkNick, message: 'Please input your nickname!' }]">
			<a-input v-model:value="formState16.nickname"></a-input>
		</a-form-item>
	
		<a-form-item name="checkNick" v-bind="formTailLayout16">
			<a-checkbox v-model:checked="formState16.checkNick">Nickname is required</a-checkbox>
		</a-form-item>
	
		<a-form-item v-bind="formTailLayout16">
			<a-button type="primary" @click="onCheck16">Check</a-button>
		</a-form-item>
	</a-form>
	
	<a-divider class="a-divi" orientation="left">多表单联动</a-divider><!-- =============================================================== -->
	<p class="desc">本例子中，Modal 的确认按钮在 Form 之外，通过 form.submit 方法调用表单提交功能。反之，则推荐使用 &lt;Button htmlType="submit" /&gt; 调用 web 原生提交逻辑。</p>
	<a-form ref="formRef17" :model="formState17" name="form_context" v-bind="layout17" style="width: 500px;margin-left: 20px"
		@finish="onFinish11" @finish-Failed="onFinishFailed11">
		<a-form-item name="group" label="Group Name" :rules="[{ required: true, message: 'Please input group name!' }]">
			<a-input v-model:value="formState17.group"></a-input>
		</a-form-item>
	
		<a-form-item label="User List" name="users">
			<template v-if="formState17.users.length">
				<ul style="list-style-type: none;margin-left: -30px;">
					<template v-for="user in formState17.users" :key="user.key">
						<li class="user" style="margin-bottom: 4px;">
							<a-avatar>
								<template #icon>
									<User-Outlined class="ant-icon"></User-Outlined>
								</template>
							</a-avatar>
							{{ user.name }} - {{ user.age }}
						</li>
					</template>
				</ul>
			</template>
			<template v-else>
				<a-typography-text class="ant-form-text" type="secondary">
					( <Smile-Outlined class="ant-icon"></Smile-Outlined> No user yet. )
				</a-typography-text>
			</template>
		</a-form-item>
	
		<a-form-item v-bind="tailLayout17">
			<a-button html-type="submit" type="primary">Submit</a-button>
			<a-button html-type="button" style="margin: 0 8px" @click="visible17 = true">Add User</a-button>
		</a-form-item>
	</a-form>
	<a-modal v-model:open="visible17" title="Basic Drawer" @ok="onOk17">
		<a-form ref="modalFormRef17" :model="modalFormState17" layout="vertical" name="userForm">
			<a-form-item name="name" label="User Name" :rules="[{ required: true }]">
				<a-input v-model:value="modalFormState17.name"></a-input>
			</a-form-item>
			<a-form-item name="age" label="User Age" :rules="[{ required: true }]">
				<a-input-number v-model:value="modalFormState17.age"></a-input-number>
			</a-form-item>
		</a-form>
	</a-modal>
	
	<a-divider class="a-divi" orientation="left">弹出层中的新建表单</a-divider><!-- =============================================================== -->
	<p class="desc">当用户访问一个展示了某个列表的页面，想新建一项但又不想跳转页面时，可以用 Modal 弹出一个表单，用户填写必要信息后创建新的项。</p>
	<div style="margin-left: 20px;">
		<a-button type="primary" @click="visible18 = true">New Collection</a-button>
		<a-modal v-model:open="visible18" title="Create a new collection" ok-text="Create" cancel-text="Cancel" @ok="onOk18">
			<a-form ref="formRef18" :model="formState18" layout="vertical" name="form_in_modal">
				<a-form-item name="title" label="Title" :rules="[{ required: true, message: 'Please input the title of collection!' }]">
					<a-input v-model:value="formState18.title" />
				</a-form-item>
				<a-form-item name="description" label="Description">
					<a-textarea v-model:value="formState18.description" />
				</a-form-item>
				<a-form-item name="modifier" class="collection-create-form_last-form-item">
					<a-radio-group v-model:value="formState18.modifier">
						<a-radio value="public">Public</a-radio>
						<a-radio value="private">Private</a-radio>
					</a-radio-group>
				</a-form-item>
			</a-form>
		</a-modal>
	</div>
	
	<a-divider class="a-divi" orientation="left">时间类控件</a-divider><!-- =============================================================== -->
	<p class="desc">时间类组件的 value 类型为 dayjs 对象，所以在提交服务器前需要预处理。或者使用 valueFormat 组件内部会自动处理。</p>
	<a-form :model="formState19" name="time_related_controls" v-bind="formItemLayout19"
		@finish="onFinish11" @finish-Failed="onFinishFailed11" style="width: 800px;">
		<a-form-item name="date-picker" label="DatePicker" v-bind="config19">
			<a-date-picker v-model:value="formState19['date-picker']" value-format="YYYY-MM-DD"></a-date-picker>
		</a-form-item>
		<a-form-item name="date-time-picker" label="DatePicker[showTime]" v-bind="config19">
			<a-date-picker v-model:value="formState19['date-time-picker']" show-time format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"></a-date-picker>
		</a-form-item>
		<a-form-item name="month-picker" label="MonthPicker" v-bind="config19">
			<a-date-picker v-model:value="formState19['month-picker']" value-format="YYYY-MM" picker="month"></a-date-picker>
		</a-form-item>
		<a-form-item name="range-picker" label="RangePicker" v-bind="rangeConfig19">
			<a-range-picker v-model:value="formState19['range-picker']" value-format="YYYY-MM-DD"></a-range-picker>
		</a-form-item>
		<a-form-item name="range-time-picker" label="RangePicker[showTime]" v-bind="rangeConfig19">
			<a-range-picker v-model:value="formState19['range-time-picker']" show-time format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" />
		</a-form-item>
		<a-form-item name="time-picker" label="TimePicker" v-bind="config19">
			<a-time-picker v-model:value="formState19['time-picker']" format="HH:mm:ss" value-format="HH:mm:ss"></a-time-picker>
		</a-form-item>
		<a-form-item :wrapper-col="{xs: { span: 24, offset: 0 }, sm: { span: 16, offset: 8 },}">
			<a-button type="primary" html-type="submit">Submit</a-button>
		</a-form-item>
	</a-form>
	
	
	
</div>
<div class="h100"></div>

</body>
<script>
const Main = {
data() {
	return {
		fileIndex: 2,
		
		formState11: {
			user: {name: '', age: undefined, email: '', website: '', introduction: '',},
		},
		layout11: {
			labelCol: { span: 8 },
			wrapperCol: { span: 16 },
		},
		validateMessages11: {
			required: '${label} is required!',
			types: {
				email: '${label} is not a valid email!',
				number: '${label} is not a valid number!',
			},
			number: {
				range: '${label} must be between ${min} and ${max}',
			},
		},
		
		formState12: {
			price: {number: 0, currency: 'rmb',},
		},
		
		formState13: {},
		expand13: false,
		
		formState14: {
			sights: [],
			area: undefined,
		},
		areas14: [
			{ label: 'Beijing', value: 'beijing' },
			{ label: 'Shanghai', value: 'shanghai' },
		],
		sights14: {
			beijing: ['Tiananmen', 'Great Wall'],
			shanghai: ['Oriental Pearl', 'The Bund'],
		},
		
		formState15: {
			users: [],
		},
		
		formState16: {
			username: '',
			nickname: '',
			checkNick: false,
		},
		formItemLayout16: {labelCol: { span: 4 }, wrapperCol: { span: 8 },},
		formTailLayout16: {labelCol: { span: 4 }, wrapperCol: { span: 8, offset: 4 },},
		
		visible17: false,
		formState17: {group: '', users: [],},
		modalFormState17: {name: '', age: null},
		layout17: {labelCol: { span: 8 }, wrapperCol: { span: 16 },},
		tailLayout17: {wrapperCol: { offset: 8, span: 16 },},
		
		visible18: false,
		formState18: {title: '', description: '', modifier: 'public',},
		
		formState19: {},
		formItemLayout19: {
			labelCol: {xs: { span: 24 },sm: { span: 8 },},
			wrapperCol: {xs: { span: 24 },sm: { span: 16 },},
		},
		config19: {
			rules: [{ required: true, type: 'string', message: 'Please select time!' }],
		},
		rangeConfig19: {
			rules: [{ required: true, type: 'array', message: 'Please select time!' }],
		},
		
		
		
		
	}
},
computed: {
	btn(){
		return function(i){
			return this.fileIndex == i ? "layui-btn" : "layui-btn0";
		}
	},
},
methods:{
	onFinish11(values){
		console.log('onFinish11 Success:', values);
	},
	onFinishFailed11(errorInfo){
		console.log('onFinishFailed11:', errorInfo);
	},
	
	checkPrice12(rule, value, callback){
		if (value > 0) {
			return callback();
		}
		return callback(new Error('Price 必须大于0!'));
	},
	
	resetForm13(){
		this.$refs.formRef13.resetFields();
	},
	
	removeSight14(item){
		const index = this.formState14.sights.indexOf(item);
		if (index !== -1) {
			this.formState14.sights.splice(index, 1);
		}
	},
	addSight14(){
		this.formState14.sights.push({
			value: undefined,
			price: undefined,
			id: Date.now(),
		});
	},
	
	removeUser15(item){
		const index = this.formState15.users.indexOf(item);
		if (index !== -1) {
			this.formState15.users.splice(index, 1);
		}
	},
	addUser15(){
		this.formState15.users.push({
			first: '',
			last: '',
			id: Date.now(),
		});
	},
	
	onCheck16(){
		try {
			const values = this.$refs.formRef16.validateFields();
			console.log('验证结果:', values);
		} catch (errorInfo) {
			console.log('Failed:', errorInfo);
		}
	},
	
	onOk17(){
		this.$refs.modalFormRef17.validateFields().then(() => {
			console.log('onOk17', this.modalFormState17);
			this.formState17.users.push({ ...this.modalFormState17, key: Date.now() });
			this.visible17 = false;
		}).catch(error => {
			console.log('error', error);
		});
	},
	
	onOk18(){
		this.$refs.formRef18.validateFields().then(values => {
			console.log('收到的表单值: ', values);
			console.log('formState18: ', Vue.toRaw(this.formState18));
			this.visible18 = false;
			this.$refs.formRef18.resetFields();
			console.log('reset formState18: ', Vue.toRaw(this.formState18));
		}).catch(info => {
			console.log('Validate Failed:', info);
		});
	},
	
	
},
watch:{
	'formState14.area':function(value){
		console.log('formState14.area 的值为：' + value);
		this.formState14.sights = [];
	},
	'formState16.checkNick': function(value){
		console.log('formState16.checkNick 的值为：' + value);
		this.$refs.formRef16.validateFields(['nickname']);
	},
	visible17: function(value){
		this.modalFormState17 = {name: '', age: null};
	},
	
},
}

const app = Vue.createApp(Main);
for (const [key, component] of Object.entries(AntdIconsVue)) {app.component(key, component)};
app.use(antd);
let vm = app.mount("#app");


</script>
</html>
